#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "../tcpchatdemo.h"

#include <QMessageBox>
#include <QDebug>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    tcpSocket(new QTcpSocket(this))
{
    stream.setDevice(tcpSocket);

    connect(tcpSocket, SIGNAL(readyRead()), SLOT(on_readyRead()));
    connect(tcpSocket, SIGNAL(disconnected()), SLOT(on_disconnected()));
    connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(on_stateChanged(QAbstractSocket::SocketState)));
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(on_error(QAbstractSocket::SocketError)));

    ui->setupUi(this);

    if(!qEnvironmentVariableIsEmpty("SERVER_ADDRESS")) {
        ui->txt_IP->setText(QString::fromLocal8Bit(qgetenv("SERVER_ADDRESS")));
    }

    time.start();
    autoWriter.setTimerType(Qt::PreciseTimer);
    connect(&autoWriter, &QTimer::timeout, [&](){
        qDebug() << "Times : " << time.elapsed() << "ms";
        count++;
        int size = (count % 9) + MAX_SIZE;
        QByteArray data(size, 'A');
        stream << data;
        QString message = QString::fromLocal8Bit(data);
        message.remove(0, MAX_SIZE - 10);
//        ui->txt_Message->appendPlainText(tr("%1").arg(message));
        time.start();
    });

    connect(&speedCalc, &QTimer::timeout, [&](){
        QString unit;
        qreal value;
        if(bytes < 1024) {
            unit = "B/s";
            value = bytes;
        }else if(bytes < 1024 * 1024) {
            unit = "K/s";
            value = bytes / 1024.0;
        }else if(bytes < 1024 * 1024 * 1024) {
            unit = "M/s";
            value = bytes / (1024.0 * 1024.0);
        }else {
            unit = "G/s";
            value = bytes / (1024.0 * 1024.0 * 1024.0);
        }
        bytes = 0;
        ui->txt_Speed->setText(tr("%1 %2").arg(value).arg(unit));
        ui->txt_Count->setText(tr("%1 行").arg(count));
    });
    speedCalc.setInterval(1000);

    this->do_disconnect();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::do_connect()
{
    ui->btn_Connect->setVisible(false);
    ui->btn_Disconnect->setVisible(true);
    ui->btn_Send->setEnabled(true);
    ui->btn_Send->setVisible(true);
    ui->btn_Stop->setVisible(false);
    ui->txt_IP->setReadOnly(true);
    ui->txt_Port->setReadOnly(true);
    ui->txt_Message->clear();
    speedCalc.start();
}

void MainWindow::do_disconnect()
{
    ui->btn_Connect->setVisible(true);
    ui->btn_Disconnect->setVisible(false);
    ui->btn_Send->setEnabled(false);
    ui->btn_Send->setVisible(true);
    ui->btn_Stop->setVisible(false);
    ui->txt_IP->setReadOnly(false);
    ui->txt_Port->setReadOnly(false);
    speedCalc.stop();
    autoWriter.stop();
}

void MainWindow::on_readyRead()
{
    while (!stream.atEnd()) {
        qint32 size;

        stream.startTransaction();

        stream >> size;
        QByteArray data(size, 0);
        stream.readRawData(data.data(), data.size());

        if(stream.commitTransaction()) {
            bytes += size;
            QString message = QString::fromLocal8Bit(data);
            message.remove(0, MAX_SIZE - 10);
            ui->txt_Message->appendPlainText(tr("%1").arg(message));
            ui->txt_Count->setText(tr("%1 行").arg(ui->txt_Message->document()->lineCount()));
        }else{
            qDebug() <<"[ Server ] : read failed!";
            return;
        }

    }
}

void MainWindow::on_disconnected()
{
    ui->statusBar->showMessage(tr("连接已经断开！"));

    this->do_disconnect();
}

void MainWindow::on_stateChanged(QAbstractSocket::SocketState state)
{
    qDebug() << state;
}

void MainWindow::on_error(QAbstractSocket::SocketError error)
{
    qDebug() << error;
    ui->statusBar->showMessage(tr("连接出错：%1").arg(tcpSocket->errorString()));
}

void MainWindow::on_btn_Connect_clicked()
{
    tcpSocket->connectToHost(ui->txt_IP->text(), ui->txt_Port->value());
    if(!tcpSocket->waitForConnected()) {
        QMessageBox::critical(this, tr("TCP客户端"),
                              tr("无法连接服务： %1.")
                              .arg(tcpSocket->errorString()));
        return;
    }

    this->do_connect();
}

void MainWindow::on_btn_Disconnect_clicked()
{
    tcpSocket->disconnectFromHost();
    if(tcpSocket->state() != QAbstractSocket::UnconnectedState &&
            !tcpSocket->waitForDisconnected()) {
        QMessageBox::critical(this, tr("TCP客户端"),
                              tr("无法断开连接： %1.")
                              .arg(tcpSocket->errorString()));
        return;
    }

    this->do_disconnect();
}

void MainWindow::on_btn_Send_clicked()
{
    autoWriter.start(1);
    ui->btn_Send->setVisible(false);
    ui->btn_Stop->setVisible(true);
}

void MainWindow::on_btn_Stop_clicked()
{
    autoWriter.stop();
    ui->btn_Send->setVisible(true);
    ui->btn_Stop->setVisible(false);
}
